home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v17n05 / res_c.asc < prev    next >
Encoding:
Text File  |  1992-03-30  |  22.8 KB  |  654 lines

  1. _BRIDGING THE GAP WITH RESIDENT_C_
  2. by Charles Albert Mirho
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. /* tsr.h */
  8. #define  FALSE 0
  9. #define  TRUE  1
  10.  
  11. /* Some commonly used scan codes */
  12. #define SC_ESCAPE      0x01
  13. #define SC_PRTSC       0x37
  14. #define SC_SPACE_BAR   0x39
  15. #define SC_CAP_LOCK    0x3A
  16. #define SC_NUM_LOCK    0x45
  17. #define SC_SCROLL_LOCK 0x46
  18.  
  19. /* toggle key codes for inittsr() */
  20. #define ALT_KEY     0x08
  21. #define CTRL_KEY    0x04
  22. #define LEFT_SHIFT  0x02
  23. #define RIGHT_SHIFT 0x01
  24.  
  25. /* TSR signature */
  26. #define SIG            *((unsigned int *)"ESI")
  27.  
  28. extern unsigned char Tsr24Result, Tsr24Error;   /* used for int24 */
  29.  
  30. struct HKEYS{
  31.     unsigned char hotscancode;
  32.     unsigned char hottoggle;
  33.     unsigned char key_identifier;
  34.     };
  35.  
  36. struct sharedata{                /* shared structure definition */
  37.     unsigned oldpsp;
  38.     unsigned ourpsp;
  39.     unsigned ourextra;
  40.     unsigned tsr_size;
  41.     unsigned tsr_stat;
  42.     unsigned char hottoggle;
  43.     unsigned char hotscancode;
  44.     unsigned char safewait;
  45.     unsigned char oldbreak;
  46.     unsigned char freeflag;
  47.     unsigned char beepflag;
  48.     unsigned char more_hotkeys;
  49.     unsigned char cdummy;
  50.     struct HKEYS far *hotkey_data;
  51.     int far *indosflag;
  52.     int far *critflag;
  53.     int far *oldint8;
  54.     int far *oldint9;
  55.     int far *oldint10;
  56.     int far *oldint13;
  57.     int far *oldint16;
  58.     int far *oldint1b;
  59.     int far *oldint1c;
  60.     int far *oldint21;
  61.     int far *oldint23;
  62.     int far *oldint24;
  63.     int far *oldint28;
  64.     int far *shareptr;
  65.     unsigned int oldss;
  66.     unsigned int oldsp;
  67.     unsigned int ourss;
  68.     unsigned int oursp;
  69.     int far *resident;
  70.     int far *dosstack;
  71.     int far *olddta;
  72.     int far *ourdta;
  73.         unsigned int ourcs;
  74.     unsigned long vec_table[256];
  75.     unsigned long our_floats[44];
  76.     unsigned long float_hold[44];
  77.     };
  78.  
  79.  
  80.  
  81.  
  82. [LISTING TWO]
  83.  
  84. /**************************************************************************
  85. *  File Name: tsr.c
  86. *  Description: Main body of the TSR. Traps hot keys LSHIFT-ALT-C (copy text),
  87. *  LSHIFT-ALT-P (paste text), LSHIFT-ALT-R (remove TSR from memory).
  88. **************************************************************************/
  89. #include <stdio.h>
  90. #include <dos.h>
  91. #include "tsr.h"
  92. #include "isr.h"
  93. #include "clip.h"
  94.  
  95. extern unsigned long cculMode;
  96. extern int cciColumns;
  97. extern int cciRows;
  98. extern BYTE far *ccfpVidMem;
  99. extern ATTRIBUTE  ccatDef25x80;
  100. extern ATTRIBUTE  ccatSecond25x80;
  101. extern BYTE *ccabAttrBuffer;                    //Undo buffer of attributes
  102. char szDataBuffer[3000] = "Yo de do de do.";    //Holds transfer data
  103. BOOL bNewData = FALSE;
  104.  
  105. #define SCAN_C                    46       //popup scan code
  106. #define SCAN_P                    25       //popup scan code
  107. #define SCAN_R                    19       //menu scan code
  108. unsigned int uiCCSig = 0x9191;             //randomly selected signature code
  109. extern int _hotkey_num;                    //will hold value of hot key pressed
  110.                                            //additional hot keys to trap
  111. extern char *kb_str_ptr;                   //points to buffer for the
  112.                                            //keystuffer routine to use
  113. extern unsigned kb_in_progress;            //non-zero if more bytes waiting
  114.                                            //in buffer to be stuffed
  115. extern int _hotkey_hit;                    //true if a hot key was pressed
  116. struct HKEYS ahkHotKeys[] =
  117. {
  118.     SCAN_R, LEFT_SHIFT | ALT_KEY, 1,
  119.     SCAN_C, LEFT_SHIFT | ALT_KEY, 2,
  120. };
  121. void tsrpost ();
  122. void tsrpre ();
  123. void vResprog();                 //function which gets control upon invocation
  124. int isr60();
  125. int isr61();
  126.  
  127. RECTANGLE rtScreen;
  128. RECTANGLE rtRect = {20,5,20,5};
  129.  
  130. /****************************************************************************
  131.     FUNCTION: Main
  132.     PURPOSE:  Main of TSR program
  133. ****************************************************************************/
  134. main (int argc, char *argv[])
  135. {
  136. int irc;
  137.     cciColumns = 80;
  138.     cciRows = 25;
  139.     ccfpVidMem = (unsigned char far *) 0xB8000000;
  140.     MAKEATTRIBUTE (ccatDef25x80, COLOR_TEXT_BLUE, COLOR_TEXT_RED, 
  141.                                                       INTENSITY_HIGH, NOBLINK);
  142.     MAKEATTRIBUTE (ccatSecond25x80, COLOR_TEXT_RED, COLOR_TEXT_BLUE, 
  143.                                                       INTENSITY_HIGH, NOBLINK);
  144.     if ((ccabAttrBuffer = (BYTE *) calloc (cciColumns*cciRows, 
  145.                                                           sizeof(BYTE)))==NULL)
  146.     {
  147.         printf ("Allocation error\n");
  148.     }  //End if (not enough memory)
  149.        //Test if TSR already loaded.  If not, do initialization code
  150.     if (!tsrloaded (uiCCSig))
  151.     {
  152.             //initialization code
  153.             //initializes a TSR that works off the system timer
  154.     if ((irc=inittsr (LEFT_SHIFT|ALT_KEY, SCAN_P, vResprog, 1000, uiCCSig, SIG,
  155.              (void far *) 0L)) != 0)
  156.         {
  157.             printf ("Error loading TSR: Error %d\n", irc);
  158.             return 1;
  159.         } //End if (failed to initialize TSR)
  160.     }  //End if (TSR not loaded already)
  161.  
  162. } //End function (main)
  163.  
  164. /* This function is called on every clock tick, approx. 18 times per sec.
  165.    It should do its processing and exit as quickly as possible */
  166. void vResprog ()
  167. {
  168. static bStuffing = FALSE;
  169.         //The variable kb_in_progress holds the number of bytes
  170.         //remaining in the buffer that need to be stuffed into application.
  171.     if(kb_in_progress)
  172.     {
  173.         return;
  174.     } //End if (in the middle of stuffing keystrokes)
  175.     if (!_hotkey_hit)
  176.     {
  177.         return;
  178.     } //End if (no hot key pressed)
  179.       //If we were previously stuffing but now we are done, clean up
  180.     if (bStuffing && !kb_in_progress)
  181.     {
  182.         bStuffing = FALSE;
  183.         kb_close ();
  184.     } //End if (done stuffing)
  185.     if (_hotkey_hit)
  186.     {
  187.         _hotkey_hit = 0;
  188.         if (_hotkey_num == 0)
  189.         {
  190.                 //Now initiate the hook function kybdstuf2() to stuff
  191.                 //all the bytes in the buffer into the application
  192.             kb_str_ptr = szDataBuffer;
  193.             kb_in_progress = strlen(szDataBuffer);
  194.             kb_init();
  195.             bStuffing = TRUE;
  196.             return;
  197.         } //End if (hot key to paste)
  198.         if (_hotkey_num == 1)
  199.         {
  200.             if (freetsr())
  201.             {
  202.                 printf ("Error - could not free tsr.\n");
  203.             }  //End if (failed to free)
  204.             freeisr1 ();
  205.             freeisr2 ();
  206.         } //End if (hot key to free tsr)
  207.         if (_hotkey_num == 2)
  208.         {
  209.             cciSaveAttrRect(&rtScreen);
  210.             if (cciHilightRect(&rtRect) == ccSUCCESS)
  211.             {
  212.                 cciSaveCharRect (&rtRect);
  213.                 bNewData = TRUE;
  214.             } //End if (sucessful highlight)
  215.             cciRestoreAttrRect(&rtScreen);
  216.         } //End if (hot key to clip screen)
  217.     } //End if (hot key hit)
  218. } //End function (vRespProg)
  219.  
  220. void tsrpre ()
  221. {
  222.     tsrhotkeys (uiCCSig, (struct HKEYS far *)ahkHotKeys, 2);
  223.     MAKERECTANGLE (rtScreen, 0, 0, cciColumns-1, cciRows-1);
  224.     initisr1 (0x60, isr60, 1);
  225.     initisr2 (0x61, isr61, 1);
  226.     printf ("TSR Loaded.\n");
  227.     printf ("LSHIFT-ALT-C to copy\n");
  228.     printf ("LSHIFT-ALT-P to paste\n");
  229.     printf ("LSHIFT-ALT-R to remove from memory\n");
  230.     return;
  231. } //End function (tsrpre)
  232. void tsrpost ()
  233. {
  234.     if (ccabAttrBuffer)
  235.     {
  236.         free (ccabAttrBuffer);
  237.     }  //End if (attribute buffer defined)
  238.     printf ("\n** TSR removed from memory. **");
  239.     printf ("\n** Hit enter to continue. **\n");
  240.     return;
  241. } //End function (tsrpost)
  242. char far *szTransferBuf;
  243. int i;
  244. isr60 ()
  245. {
  246.     FP_SEG (szTransferBuf) = isr1_ds;
  247.     FP_OFF (szTransferBuf) = isr1_dx;
  248.     i = 0;
  249.     while (szTransferBuf[i] != 0)
  250.     {
  251.         szDataBuffer[i++] = szTransferBuf[i];
  252.     } //End while (more bytes to transfer)
  253.     szDataBuffer[i] = 0;
  254.     return 0;
  255. } //End function (isr60)
  256. isr61 ()
  257. {
  258.     if (!bNewData)
  259.     {
  260.         isr2_ax = 0;
  261.         return 0;
  262.     } //End if (no new data to copy)
  263.     bNewData = FALSE;
  264.     FP_SEG (szTransferBuf) = isr2_ds;
  265.     FP_OFF (szTransferBuf) = isr2_dx;
  266.     i = 0;
  267.     while (szDataBuffer[i] != 0)
  268.     {
  269.         szTransferBuf[i] = szDataBuffer[i];
  270.         i++;
  271.     } //End while (more bytes to transfer)
  272.     szTransferBuf[i] = 0;
  273.     isr2_ax = 1;
  274.     return 0;
  275. } //End function (isr61)
  276.  
  277.  
  278.  
  279. [LISTING THREE]
  280.  
  281. /* Windos.h */
  282. int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
  283. long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
  284. int      pmiIntX (int iIntNo, LPSTR szSwapData);
  285.  
  286. #define  BUFFER_SIZE      3000L              //size of transfer buffer
  287. #define  TEXT_INC          15                //space between lines of text
  288. #define  SIG              "windos"           //Signature to place on clipboard
  289.  
  290.  
  291.  
  292. [LISTING FOUR]
  293.  
  294. /****************************************************************************
  295.     PROGRAM: WINDOS
  296.     PURPOSE: Reads text from the clipboard and writes it to a DOS TSR using 
  297.     DPMI. Or, reads text from a DOS TSR and writes it to clipboard.
  298. ****************************************************************************/
  299. #include "windows.h"
  300. #include "windos.h"
  301. #include "dpmi.h"
  302. #include <dos.h>
  303. #include <string.h>
  304. #include <stdlib.h>
  305.  
  306. HWND     hwndMain;                      //Global handle to main window
  307. WORD     cfSignature;                   //signature format (proprietary)
  308. char     szClipData[3000];
  309. SELECTOR PMSelector;                    //protected mode selector
  310. SEGMENT  RMSegment;                     //real-mode segment
  311. DWORD    dwSegSelector;                 //seg:selector pair returned by
  312.                                         //GlobalDosAlloc()
  313. LPSTR    lpTransferBuf;                 //Points to transfer buffer
  314.  
  315. /****************************************************************************
  316.     FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
  317.     PURPOSE: Calls initialization functions and processes message loop
  318.     Only one instance of the program is allowed to run.
  319. ****************************************************************************/
  320. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine,
  321.                    int nCmdShow)
  322. {
  323. MSG msg;
  324.  
  325.     if (!hPrevInstance)
  326.     {
  327.         if (!InitApplication(hInstance))
  328.         {
  329.             return (FALSE);
  330.         } //End if (failed initializing application params)
  331.     } //End if (no previous instance running)
  332.     else
  333.     {
  334.         return FALSE;
  335.     } //End if (previous instance already running)
  336.     if (!InitInstance(hInstance, nCmdShow))
  337.     {
  338.         return (FALSE);
  339.     } //End if (failed initializing instance data)
  340.     while (GetMessage(&msg, NULL, NULL, NULL))
  341.     {
  342.         TranslateMessage(&msg);
  343.         DispatchMessage(&msg);
  344.     } //End while (not a quit message)
  345.     return (msg.wParam);
  346. }  //End function (WinMain)
  347. /****************************************************************************
  348.     FUNCTION: InitApplication(HANDLE)
  349.     PURPOSE: Initializes window data and registers window classes
  350. ****************************************************************************/
  351. BOOL InitApplication(HANDLE hInstance)
  352. {
  353. WNDCLASS  wc;
  354.     wc.style = NULL;
  355.     wc.lpfnWndProc = MainWndProc;
  356.     wc.cbClsExtra = 0;
  357.     wc.cbWndExtra = 0;
  358.     wc.hInstance = hInstance;
  359.     wc.hIcon =   LoadIcon(hInstance, "SMILEY");
  360.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  361.     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  362.     wc.lpszMenuName =  NULL;
  363.     wc.lpszClassName = "WinDos";
  364.     return (RegisterClass(&wc));
  365. } //End function (InitApplication)
  366. /****************************************************************************
  367.     FUNCTION:  InitInstance(HANDLE, int)
  368.     PURPOSE:  Saves instance handle and creates main window
  369. ****************************************************************************/
  370. BOOL InitInstance(HANDLE hInstance, int nCmdShow)
  371. {
  372. HDC         hDC;
  373. TEXTMETRIC  tm;
  374.     hwndMain = CreateWindow(
  375.         "WinDos",
  376.         "WinDos",
  377.         WS_OVERLAPPEDWINDOW,
  378.         CW_USEDEFAULT,
  379.         CW_USEDEFAULT,
  380.         CW_USEDEFAULT,
  381.         CW_USEDEFAULT,
  382.         NULL,
  383.         NULL,
  384.         hInstance,
  385.         NULL
  386.     );
  387.  
  388.     if (!hwndMain)
  389.     {
  390.         return (FALSE);
  391.     } //End if (error creating main window)
  392.     ShowWindow(hwndMain, SW_SHOWMINIMIZED);
  393.     UpdateWindow(hwndMain);
  394.     return (TRUE);
  395. } //End function (InitInstance)
  396. /****************************************************************************
  397.     FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
  398.     PURPOSE:  Processes messages for WINDOS application.
  399. ****************************************************************************/
  400. long FAR PASCAL MainWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
  401. {
  402. HANDLE hClipData, hSig;
  403. LPSTR lpClipData, lpSig;
  404. int i, j;
  405.     switch (message)
  406.     {
  407.         case WM_CREATE:
  408.             if (GetWinFlags() & WF_ENHANCED)
  409.             {
  410.    MessageBox (hWnd, "Cannot use WINDOS in 386 enhanced mode", "Error", MB_OK);
  411.                 PostQuitMessage(0);
  412.                 break;
  413.             } //End if (running 386 enhanced mode)
  414.                 // Allocate the transfer buffer
  415.                 // Take selector from low word of return value
  416.                 // (real-mode segment is in high word)
  417.             if ((dwSegSelector = GlobalDosAlloc (BUFFER_SIZE+1))==NULL)
  418.             {
  419.          MessageBox (hWnd, "Unable to allocate transfer buf", "Error", MB_OK);
  420.                 PostQuitMessage(0);
  421.                 break;
  422.             } //End if (could not allocate transfer buf)
  423.             PMSelector = LOWORD (dwSegSelector);
  424.             RMSegment  = HIWORD (dwSegSelector);
  425.                 // Set pointer to transfer buffer
  426.             lpTransferBuf = (LPSTR) MAKELONG (0, PMSelector);
  427.                 //Register our proprietary format with the clipboard
  428.             if (!(cfSignature = RegisterClipboardFormat("Sig")))
  429.             {
  430.          MessageBox (hWnd, "Unable to register clipbd format", "Error", MB_OK);
  431.                 PostQuitMessage(0);
  432.                 break;
  433.             } //End if (error registering proprietary clipboard format)
  434.                 //Receive timer messages every 1/2 second
  435.             if (!SetTimer (hWnd, 1, 500, NULL))
  436.             {
  437.                 MessageBox (hWnd, "Unable to create timer", "Error", MB_OK);
  438.                 PostQuitMessage(0);
  439.                 break;
  440.             } //End if (could not create timer)
  441.             break;
  442.         case WM_TIMER:
  443.                 //Check the clipboard;  if signature not present, then copy
  444.                 //data.
  445.             do
  446.             {
  447.                 if (OpenClipboard(hWnd))
  448.                 {
  449.                     if (IsClipboardFormatAvailable (cfSignature))
  450.                     {
  451.                         CloseClipboard ();
  452.                         break;
  453.                     } //End if (signature present - stale data)
  454.                     else
  455.                     {
  456.                         if (IsClipboardFormatAvailable (CF_TEXT))
  457.                         {
  458.                             if (!(hClipData = GetClipboardData (CF_TEXT)))
  459.                             {
  460.                                 CloseClipboard ();
  461.                                 break;
  462.                             } //End if (error getting data from clipboard)
  463.                             if (!(lpClipData = GlobalLock (hClipData)))
  464.                             {
  465.                                 CloseClipboard ();
  466.                                 break;
  467.                             } //End if (error dereferencing clip handle)
  468.                         } //End if (text available on clipboard)
  469.                         else
  470.                         {
  471.                             CloseClipboard ();
  472.                             break;
  473.                         } //End if (no text on clipboard)
  474.                     } //End if (new data on the clipboard)
  475.                     CloseClipboard ();
  476.                 } //End if (able to open clipboard)
  477.                 else
  478.                 {
  479.                     break;
  480.                 } //End if (unable to open clipboard)
  481.  
  482.                     //Now copy the data to the TSR
  483.                     //Do the real-mode interrupt to get the TSR's attention.
  484.                 pmiIntX (0x60, lpClipData);
  485.                     //Now copy signature to clipboard
  486.     if (!(hSig = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD)lstrlen(SIG))))
  487.                 {
  488.                     break;
  489.                 } //End if (couldn't find the memory)
  490.                 if (!(lpSig = GlobalLock(hSig)))
  491.                 {
  492.                     GlobalFree(hSig);
  493.                     break;
  494.                 } //End if (couldn't lock the memory)
  495.                 lstrcpy (lpSig, SIG);
  496.                 GlobalUnlock(hSig);
  497.                 if (OpenClipboard(hWnd))
  498.                 {
  499.                     SetClipboardData(cfSignature, hSig);
  500.                     CloseClipboard();
  501.                 } //End if (clipboard open)
  502.             } while (FALSE);
  503.             do
  504.             {
  505.                 if (!pmiIntX (0x61, szClipData))
  506.                 {
  507.                     if (OpenClipboard(hWnd))
  508.                     {
  509.                             //Now copy data to clipboard; allocate a few extra
  510.                             //bytes for CR - CR-LF combos.
  511.       if (!(hClipData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD) 3300)))
  512.                         {
  513.                             CloseClipboard ();
  514.                             break;
  515.                         } //End if (couldn't find the memory)
  516.                         if (!(lpClipData = GlobalLock(hClipData)))
  517.                         {
  518.                             CloseClipboard ();
  519.                             GlobalFree(hClipData);
  520.                             break;
  521.                         } //End if (couldn't lock the memory)
  522.                             //Copy the data to clipboard buf, translating
  523.                             //CR to CR-LF combo; this is the clipboard
  524.                             //TEXT format.
  525.                         i=0;
  526.                         j=0;
  527.                         while (szClipData[j] != 0)
  528.                         {
  529.                             if (szClipData[j] == 0x0D)
  530.                             {
  531.                                 lpClipData[i] = 0x0D;
  532.                                 i++;
  533.                                 lpClipData[i] = 0x0A;
  534.                             } //End if (CR found)
  535.                             else
  536.                             {
  537.                                 lpClipData[i] = szClipData[j];
  538.                             } //End if (normal byte)
  539.                             i++;
  540.                             j++;
  541.                         } //End while (more bytes to copy)
  542.                         lpClipData[i] = 0;
  543.                         GlobalUnlock(hClipData);
  544.                             //Now copy signature to clipboard
  545.     if (!(hSig = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD)lstrlen(SIG))))
  546.                         {
  547.                             CloseClipboard ();
  548.                             break;
  549.                         } //End if (couldn't find the memory)
  550.                         if (!(lpSig = GlobalLock(hSig)))
  551.                         {
  552.                             CloseClipboard ();
  553.                             GlobalFree(hSig);
  554.                             break;
  555.                         } //End if (couldn't lock the memory)
  556.                         lstrcpy (lpSig, SIG);
  557.                         GlobalUnlock(hSig);
  558.                         EmptyClipboard();
  559.                         SetClipboardData(CF_TEXT, hClipData);
  560.                         SetClipboardData(cfSignature, hSig);
  561.                         CloseClipboard();
  562.                     } //End if (clipboard opened)
  563.                 } //End if (got data from TSR)
  564.             } while (FALSE);
  565.             break;
  566.         case WM_DESTROY:                  /* message: window being destroyed */
  567.             KillTimer (hWnd, 1);
  568.             GlobalDosFree (PMSelector);
  569.             PostQuitMessage(0);
  570.             break;
  571.         default:                          /* Passes it on if unproccessed    */
  572.             return (DefWindowProc(hWnd, message, wParam, lParam));
  573.     } //End switch (on message)
  574.     return (NULL);
  575. } //End function (MainWndProc)
  576. /****************************************************************************
  577.     FUNCTION:  pmiIntX
  578.     PURPOSE:  High level: Performs real mode interrupt
  579. ****************************************************************************/
  580. int pmiIntX (int iIntNo, LPSTR szSwapData)
  581. {
  582.     if (iIntNo == 0x60)
  583.     {
  584.             //Copy data to transfer buffer, including trailing NULL
  585.         _fmemcpy (lpTransferBuf, (LPSTR) szSwapData, lstrlen (szSwapData)+1);
  586.     } //End if (writing data TO TSR)
  587.         //If running protected mode, simulate real mode interrupt
  588.         //Otherwise do an int86x()
  589.     if (GetWinFlags() & WF_PMODE)
  590.     {
  591.     RM386_INT rmInt;                        //structure for making real-mode
  592.                                             //interrupts from protected mode
  593.         memset (&rmInt, 0, sizeof(rmInt));
  594.         rmInt.edx = 0x0000;
  595.         rmInt.ds =  RMSegment;
  596.         dpmiRMInt (iIntNo, 0, &rmInt, 0);
  597.         if (iIntNo == 0x61)
  598.         {
  599.             if (rmInt.eax == 0)
  600.             {
  601.                 return -1;
  602.             } //End if (no TSR data to read)
  603.         } //End if (reading data FROM TSR)
  604.     } //End if (running in protected mode)
  605.     else
  606.     {
  607.     union REGS inregs, outregs;
  608.     struct SREGS sregs;
  609.         sregs.ds =        RMSegment;
  610.         inregs.x.dx =     0;
  611.         int86x (iIntNo, &inregs, &outregs, &sregs);
  612.         if (iIntNo==0x61 && outregs.x.ax == 0)
  613.         {
  614.             return -1;
  615.         } //End if (no TSR data to read)
  616.     } //End if (running in real mode)
  617.     if (iIntNo == 0x61)
  618.     {
  619.             //Copy data from transfer buffer, including trailing NULL
  620.        _fmemcpy ((LPSTR) szSwapData, lpTransferBuf, lstrlen (lpTransferBuf)+1);
  621.     } //End if (reading data FROM TSR)
  622.     return 0;
  623. } //End function (pmiDPMIIntX)
  624. /****************************************************************************
  625.     FUNCTION:  pmiDPMIIntX
  626.     PURPOSE:  Low level: Performs simulated real mode interrupt using DPMI
  627. ****************************************************************************/
  628. BOOL dpmiRMInt(WORD wIntno, WORD wFlags, RM386_INT far *rmInt, WORD wStackVals)
  629. {
  630.     if (wFlags)
  631.     {
  632.         wIntno |= 0x100;
  633.     } //End if (flags set)
  634.     _asm
  635.     {
  636.         push di
  637.         mov  ax, 0300h
  638.         mov  bx, word ptr wIntno
  639.         mov  cx, word ptr wStackVals
  640.         les  di, dword ptr rmInt
  641.         int  31h
  642.         jc   error
  643.         mov  ax, 1
  644.         jmp  short done
  645.     } //End (low-level dpmi real-mode interrupt)
  646. error:
  647.     _asm xor ax, ax
  648. done:
  649.     _asm pop di
  650. } //End function (dpmiRMInt)
  651.  
  652.  
  653.  
  654.